package org.jeecg.common.core;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.Collection;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 级联操作
 * p是主表c是子表
 *
 * @author zjarlin
 * @since 2023/2/26 09:18
 */
//@Component
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MybatisPlusUtil<P, C> {

    protected IService<P> ps;

    protected IService<C> cs;

    public static <P, C> MybatisPlusUtil<P, C> of(IService<P> ps, IService<C> cs) {
        return new MybatisPlusUtil<>(ps, cs);
    }

    public boolean pSave(P p, List<C> childColl, Function<P, String> getPidFun, BiConsumer<C, String> setPkFun) {
        BiConsumer<C, P> tConsumer = (child, par) -> setPkFun.accept(child, String.valueOf(getPidFun.apply(par)));
        boolean b = false;
        try {
            b = pSave(p, childColl, tConsumer);
        } catch (Exception e) {
            return false;
        }
        return b;

    }

    /**
     * 级联新增
     *
     * @param p
     * @param childColl 子表
     * @param setFun    setPid
     * @return 是否成功
     * @author zjarlin
     * @since 2023/03/01
     */
    public boolean pSave(P p, Collection<C> childColl, BiConsumer<C, P> setFun) {
        boolean save = ps.save(p);
        return save && cSave(p, childColl, setFun);
    }

    /**
     * 子表新增
     *
     * @param p         p
     * @param childColl 孩子科尔
     * @param setFun    设置有趣 入参
     * @return boolean
     * @author zjarlin
     * @since 2023/03/01
     */
    public boolean cSave(P p, Collection<C> childColl, BiConsumer<C, P> setFun) {
        Consumer<C> cConsumer = child -> setFun.accept(child, p);
        childColl.forEach(cConsumer);
        return cs.saveBatch(childColl);
    }

    /**
     * 级联删除
     *
     * @param p          p
     * @param pgetIdFun  pget id乐趣
     * @param cgetPidFun cget pid有趣 入参
     * @return boolean
     * @author zjarlin
     * @since 2023/03/01
     */
    public boolean pRemove(P p, Function<P, String> pgetIdFun, SFunction<C, String> cgetPidFun) {
        boolean remove = ps.removeById(p);
        boolean b = cRemove(p, pgetIdFun, cgetPidFun);
        return remove && b;
    }

    /**
     * 仅删除p中给定id对应的子表
     *
     * @param p          p
     * @param pgetIdFun  pget id乐趣
     * @param cgetPidFun cget pid有趣 入参
     * @return boolean
     * @author zjarlin
     * @since 2023/03/01
     */
    public boolean cRemove(P p, Function<P, String> pgetIdFun, SFunction<C, String> cgetPidFun) {
        LambdaQueryWrapper<C> eq = Wrappers.<C>lambdaQuery().eq(cgetPidFun, pgetIdFun.apply(p));
        return cs.remove(eq);
    }

    public boolean pUpdate(P p, Collection<C> childColl, Function<P, String> pgetPidFun, SFunction<C, String> cgetPidFun, BiConsumer<C, String> csetPkFun) {
        boolean b = ps.updateById(p);
        boolean b2 = cRemove(p, pgetPidFun, cgetPidFun);
        boolean b3 = cSave(p, childColl, pgetPidFun, csetPkFun);
        return b && b2 && b3;
    }

    /**
     * c保存
     *
     * @param p         p
     * @param childColl 孩子科尔
     * @param getPidFun 得到pid有趣
     * @param setPkFun  组pk有趣 入参
     * @return boolean
     * @author zjarlin
     * @since 2023/03/01
     */
    public boolean cSave(P p, Collection<C> childColl, Function<P, String> getPidFun, BiConsumer<C, String> setPkFun) {
        BiConsumer<C, P> tConsumer = (child, par) -> setPkFun.accept(child, String.valueOf(getPidFun.apply(par)));
        return cSave(p, childColl, tConsumer);

    }

}
